#pragma once
#include "ArrayStack.h"
#include "LockHelper.h"

template <typename T>
class ConcurrentArrayStack : public ArrayStack<T>
{
private :
	LockHelper m_oLockHelper;
public :
	ConcurrentArrayStack(int a_nMaxSize);
	~ConcurrentArrayStack();

	virtual void push(T a_oData);
	virtual T pop();
	virtual bool canPush();
	virtual bool canPop();
	virtual int getDataCount();

};

template <typename T>
ConcurrentArrayStack<T>::ConcurrentArrayStack(int a_nMaxSize) : ArrayStack<T>(a_nMaxSize)
{
	
}

template <typename T>
ConcurrentArrayStack<T>::~ConcurrentArrayStack()
{
}

template <typename T>
void ConcurrentArrayStack<T>::push(T a_oData) 
{
	m_oLockHelper.lock();
	ArrayStack<T>::push(a_oData);
	m_oLockHelper.unlock();
}

template <typename T>
T ConcurrentArrayStack<T>::pop() 
{
	m_oLockHelper.lock();
	T poppedValue = ArrayStack<T>::pop();
	m_oLockHelper.unlock();
	return poppedValue;
}

template <typename T>
bool ConcurrentArrayStack<T>::canPush() 
{
	bool bRet = false;
	m_oLockHelper.lock();
	bRet = ArrayStack<T>::canPush();
	m_oLockHelper.unlock();
	return bRet;
}

template <typename T>
bool ConcurrentArrayStack<T>::canPop() 
{
	bool bRet = false;
	m_oLockHelper.lock();
	bRet = ArrayStack<T>::canPop();
	m_oLockHelper.unlock();
	return bRet;
}

template <typename T>
int ConcurrentArrayStack<T>::getDataCount()
{
	int dataCount = 0;
	m_oLockHelper.lock();
	dataCount = ArrayStack<T>::getDataCount();
	m_oLockHelper.unlock();
	return dataCount;
}